package com.wyg.lambda.example;

import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;

/**
 * Lambda表达式-复杂实例
 * <p>
 *
 *     写好Lambda表达式注意事项：1.看参数，2.看返回值。
 *
 *          第一步 先写好样式： () -> {}
 *          第二步 看参数写入参数： (int a, int b ...) -> {}
 *          第三步 看返回值，写方法体实现：  (int a, int b ...) -> { return a+b;};
 *
 * </p>
 *
 * JDK1.8提供的函数式接口： 位置rt.jar -> java.util.function包下
 *      1.java.util.function.Supplier<T>  代表输出
 *
 *      2.java.util.function.Consumer<T>  代表输入
 *      3.java.util.function.BiConsumer<T, U>  代表两个输入
 *
 *      4.java.util.function.Function<T, R>  代表一个输入，一个输出（一般表示输入和输出是【不同类型】的）
 *      5.java.util.function.UnaryOperator<T> extends Function<T, T>  代表一个输入，一个输出(输入和输出是【相同类型】的)
 *
 *      6.java.util.function.BiFunction<T, U, R> 代表两个输入，一个输出（一般表示输入和输出是【不同类型】的）
 *      7.java.util.function.BinaryOperator<T> extends BiFunction<T,T,T>  代表两个输入，一个输出(输入和输出是【相同类型】的)
 *
 *
 * @ClassName: Example_2
 * @Description: TODO
 * @Auther: WangYG
 * @Date: 2020-02-20 01:25:10
 * @Version: 1.0
 */
public class Example_2 {

    private static final int NUM_TEN = 10;

    /**
     * 功能描述: 使用Consumer<T>函数式接口演示-Lambda表达式需要传入一个参数的调用方法
     * @methodName: consumerFun
     * @params: []
     * @return: void
     * @exception:
     * @auther: WangYG
     * @date: 2020-02-20 17:03:14
     */
    public void consumerFun(){

        //1.使用普通方式调用
        Consumer<String> c1 = new Consumer<String>(){
            @Override
            public void accept(String s) {
                System.out.println("this is c1 accept() : " + s);
            }
        };
        c1.accept("consumer 接受参数演示。");

        //2.使用Lambda表达式 唯一抽象方法accept(s) -> {}
        Consumer<String> c2 = (String str) -> {
            System.out.println("this is Lambda c2 accept() : " + str);
        };
        c2.accept("Lambda consumer 接受参数演示。");

        //3.使用Lambda表达式-省略 s -> 方法体
        Consumer<String> c3 = s -> System.out.println("this is Lambda omit c3 accept() : " + s);
        c3.accept("Lambda omit consumer 接受参数演示。");
    }

    /**
     * 功能描述: 使用Supplier<T>函数式接口演示-Lambda表达式需要接收返回值的调用方法
     * @methodName: supplierFun
     * @params: []
     * @return: void
     * @exception:
     * @auther: WangYG
     * @date: 2020-02-20 17:10:53
     */
    public void supplierFun(){
        //1.普通调用方式-获取返回值
        Supplier<String> s1 = new Supplier<String>(){
            @Override
            public String get() {
                return "this is Supplier s1 get().";
            }
        };
        System.out.println(s1.get());

        //2.使用Lambda表达式-获取返回值 唯一抽象方法 get() -> {}
        Supplier<String> s2 = () -> {return "this is Supplier Lambda s2 get().";};
        System.out.println(s2.get());

        //3.使用Lambda表达式-省略-获取返回值 () -> "";
        Supplier<String> s3 = () -> "this is Supplier Lambda omit s3 get().";
        System.out.println(s3.get());
    }


    /**
     * 功能描述: 使用Function<Integer,Integer>接口，演示Lambda表示一个入参和一个出参的使用方式
     * @methodName: complexOne
     * @params: []
     * @return: void
     * @exception:
     * @auther: WangYG
     * @date: 2020-02-20 01:35:03
     */
    public void complexOne(){

        //1.普通使用方法
        Function<Integer,Integer> fun = new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer integer) {
                System.out.println("this is fun apply().");
                int sum = 0;
                for (Integer i = 0; i <= integer; i++) {
                    sum += i;
                }
                return sum;
            }
        };
        System.out.println(fun.apply(NUM_TEN));


        //2.lambda使用方式 ：唯一抽象方法apply(Integer integer) -> {方法体实现 return 1;};
        //  入参仅有一个，可以省略类型和小括号()
        Function<Integer,Integer> fun2 = a -> {
            System.out.println("this is lambda fun2 apply().");
            int sum = 0;
            for (Integer i = 0; i <= a; i++) {
                sum += i;
            }
            return sum;
        };
        System.out.println(fun2.apply(NUM_TEN));
    }

    /**
     * 功能描述: 使用BiFunction<String,String,Integer>接口，演示Lambda表示两个入参和一个出参的使用方式
     * @methodName: complexTwo
     * @params: []
     * @return: void
     * @exception:
     * @auther: WangYG
     * @date: 2020-02-20 02:07:58
     */
    public void complexTwo(){

        //1.普通使用方法
        BiFunction<String,String,Integer> biFun = new BiFunction<String, String, Integer>() {
            @Override
            public Integer apply(String s, String s2) {
                return s.length() + s2.length();
            }
        };
        System.out.println("普通使用方法：" + biFun.apply("java","HelloWorld"));

        //2.使用Lambda表达式 -> 唯一抽象方法 apply(参数...) -> {方法体实现 return;}
        BiFunction<String,String,Integer> biFun2 = (String s, String s2) -> {return s.length() + s2.length();};
        System.out.println("使用Lambda表达式：" + biFun2.apply("java","HelloWorld"));

        //3.使用Lambda表达式-省略方式 -> 1.省略参数类型，2.省略方法体中return和{}
        BiFunction<String,String,Integer> biFun3 = (s, s2) -> s.length() + s2.length();
        System.out.println("使用Lambda表达式-省略方式：" + biFun3.apply("java","HelloWorld"));

    }

}
